<template>
  <s-layout class="chat-wrap" :title="state.friend_info.nickname" :isAI="true" navbar="inner" :is_main-body="true"
            color="#FFEBA3" :is_back="true" :ncShareInfo="state.ncShareInfo"
            :customBody="customBody()" @touchend="onTouchStart">
    <view class="w-100 flex flex-column flex-sub position-relative">
      <!-- 消息内容 -->
      <view class="w-100" :style="{
                          height: `calc(100vh - ${scrollView}px)`
                     }" style="position: relative">
        <scroll-view id="scrollView" class="scrollViewChat w-100"
                     :style="{
                          height: `calc(100vh - ${scrollView}px)`
                     }"
                     :scroll-anchoring="true" :scroll-top="state.messageListHeight" :scroll-y="true"
                     style="background: #212124">
          <message class="w-100" :chatInfo="state.chat_info" :friendInfo="state.friend_info"
                   :chatListLength="state.message_list.length" :subscript="index" :shareFlag="share.flag"
                   :user-info="state.user_info" v-for="(item,index) in state.message_list" :key="index"
                   :info="item" @playSound="playVoice"
                   @clickToSelect="clickToSelect"></message>
        </scroll-view>
      </view>
      <send id="send" ref="send" :friendInfo="state.friend_info" :textInput="sendState.textInput"
            :shareFlag="share.flag" :isShare="true"
            :showTaskbar="sendState.showTaskbar" @submit="submit" @shareNow="shareNow"
            @bottomHeight="bottomHeight" @unshare="unshare"
            @taskbarHeight="taskbarHeight" @toggleMode="toggleMode" @toggle="toggle"></send>
    </view>
  </s-layout>

  <!-- 会员弹窗 -->
  <s-popup-vip :show="vipDisposition.isShow" @closePopup="closePopup">
    <template #default>
      <view class="memberPopup position-relative"
            v-if="!!vipDisposition.goodDetails && vipDisposition.goodDetails != {}">
        <image class="w-100 h-100" :src="`${nc_image_path}/nc_vip_banner.png`"></image>
        <view class="exchange flex align-center justify-between">
          <view class="flex align-end" v-if="!!vipDisposition.goodDetails.price">
            <text>￥</text>
            <text class="fs_60" style="line-height: 60rpx">{{ vipDisposition.goodDetails.price[0] }}</text>
          </view>
          <view @click.stop="exchangeImmediately">
            兑换
          </view>
        </view>
        <view class="chatDetail fs_26 fw_500" style="color: #FDD07F"
              @click.stop="sheep.$router.go('/pages/public/richtext',{id:4,title:'会员权益'})"
        >
          查看详情
        </view>
        <view class="button_vip flex flex-row align-center justify-center" @click.stop="openImmediately">
          立即开通
        </view>
      </view>
    </template>
  </s-popup-vip>
</template>

<script setup>
  import { onLoad, onUnload } from '@dcloudio/uni-app';
  import { computed, getCurrentInstance, nextTick, onMounted, reactive, ref } from 'vue';
  import sheep from '@/sheep';
  import Send from '@/pages/nc_chat/components/send.vue';
  import SLayout from '@/sheep/components/s-layout/s-layout.vue';
  import Message from '@/pages/nc_chat/components/message.vue';
  import SPopupVip from '@/sheep/components/s-popup-vip/s-popup-vip.vue';

  const customBody = () => {
    return {
      'display': 'flex',
      'flex-direction': 'column',
      'align-items': 'center',
    };
  };
  const { proxy } = getCurrentInstance();
  const nc_image_path = computed(() => sheep.$store('AI').nc_image_path);
  const setImageStyle = (width, height) => {
    return {
      'width': width + 'rpx',
      'height': height + 'rpx',
    };
  };

  const state = reactive({
    chat_info: {},
    friend_info: {},
    user_info: {},
    message_list: [],
    sendHeight: 0,
    bottomHeight: 0,
    requestTask: null,
    messageListHeight: 0,
    messageListChat: {
      page: 1,
      pageSize: 15,
      total: 0,
    },
    ncShareInfo: {},
  });
  const vipDisposition = reactive({
    isShow: false,
    goodDetails: {},
  });
  const sendState = reactive({
    textInput: true,
    showTaskbar: false,
  });
  const share = reactive({
    flag: false,
  });
  const userInfo = computed(() => sheep.$store('user').userInfo);
  const bind_id = computed(() => sheep.$store('AI').bind_id);
  const isLogin = computed(() => sheep.$store('user').isLogin);


  const scrollView = computed(() => {
    return state.sendHeight + Number(sheep.$platform.device.statusBarHeight) + 44 + state.bottomHeight;
  });
  let requestTask = null;

  onLoad(async (options) => {
    state.chat_info.id = options.id;
    if (!!options.uid) {
      sheep.$store('AI').setBindId(options.uid);
    }
  });

  onMounted(async () => {
    // 绑定用户
    if (!!bind_id.value && !!isLogin.value) {
      const res = await sheep.$api.user.bindParent({ parent_id: bind_id.value });
    }
    const { data } = await sheep.$api.goods.ids({ ids: '10' });
    vipDisposition.goodDetails = data[0];
    await getMessageList();
    sendHeight();
    setScrollTop();
  });

  // 获取底部高度
  function sendHeight() {
    nextTick(() => {
      const query = uni.createSelectorQuery().in(proxy);
      query.select('#send').boundingClientRect((rect) => {
        state.sendHeight = rect.height;
      }).exec();
    });
  }

  // 获取消息列表
  const getMessageList = async (flag = true) => {
    const { data } = await sheep.$api.share.getShareList({ id: state.chat_info.id });
    state.friend_info = data.friend;
    state.user_info = data.user;
    state.messageListChat.total = data.total;
    let newArr = [];
    data.chatList.forEach((item) => {
      item.isPlay = false;
      newArr.push(item);
    });
    state.message_list = [...state.message_list, ...newArr];
    for (let i = 0; i < state.message_list.length; i++) {
      state.message_list[i].is_decimalPoint = false;
      state.message_list[i].is_select = false;
    }
    // 初始化消息内容
    if (state.message_list.length <= 0) {
      state.message_list.unshift({
        bot_id: null,
        chat_id: null,
        conversation_id: null,
        createtime: new Date().getTime() / 1000,
        follow_up: !!data.suggested_questions ? data.suggested_questions : [],
        id: null,
        is_read: 0,
        message: !!data.onboardingInfo ? data.onboardingInfo : '',
        receiver_id: state.user_info.id,
        sender_id: state.friend_info.id,
        type: 'text',
        update_time: new Date().getTime() / 1000,
        is_decimalPoint: false,
      });
      await sheep.$store('AI').setAllSessionList();
      await sheep.$store('AI').setAllFollowList();
    }
  };


  /**
   * 处理提交的对象
   * 根据对象的类型执行不同的操作
   * @param {Object} obj - 提交的对象
   * @param {string} obj.type - 对象的类型，可以是 'text', 'audio', 'image'
   */
  function submit(obj) {
    switch (obj.type) {
      case 'text':
        sendText(obj);
        break;
      case 'audio':
        sendAudio(obj);
        break;
      case 'image':
        sendImage(obj);
        break;
    }
  }

  async function foll_sumbit(item) {
    if (!userInfo.value.vip_end_time || Number(userInfo.value.vip_end_time) < Number(new Date().getTime() / 1000)) {
      vipDisposition.isShow = true;
      return;
    }
    let { data } = await sheep.$api.chat.nc_sendText({
      content: item,
      friend_id: state.friend_info.id,
      user_id: state.user_info.id,
      type: 'text',
    });
    setMessageContent(data, 'text');
    setScrollTop();
    getAINews(item, 'text');
  }

  // 发送文本消息
  const sendText = async (obj) => {
    if (!userInfo.value.vip_end_time || Number(userInfo.value.vip_end_time) < Number(new Date().getTime() / 1000)) {
      vipDisposition.isShow = true;
      return;
    }
    let { data } = await sheep.$api.chat.nc_sendText({
      content: obj.chatValue,
      friend_id: state.friend_info.id,
      user_id: state.user_info.id,
      type: 'text',
    });
    setMessageContent(data, 'text');
    setScrollTop();
    getAINews(obj.chatValue, 'text');
  };

  // 发送语音消息
  const sendAudio = async (obj) => {
    if (!userInfo.value.vip_end_time || Number(userInfo.value.vip_end_time) < Number(new Date().getTime() / 1000)) {
      vipDisposition.isShow = true;
      return;
    }
    let { data } = await sheep.$api.chat.nc_sendText({
      content: obj.data.fullurl,
      friend_id: state.friend_info.id,
      user_id: state.user_info.id,
      type: 'voice',
    });
    setMessageContent(data, 'voice');
    setScrollTop();
    getAINews(obj.data.fullurl, 'voice');
  };

  // 发送图片消息
  const sendImage = async (obj) => {
    if (!userInfo.value.vip_end_time || Number(userInfo.value.vip_end_time) < Number(new Date().getTime() / 1000)) {
      vipDisposition.isShow = true;
      return;
    }
    let { data } = await sheep.$api.chat.nc_sendText({
      content: obj.data.fullurl,
      friend_id: state.friend_info.id,
      user_id: state.user_info.id,
      type: 'image',
    });
    setMessageContent(data, 'image');
    setScrollTop();
    getAINews(obj.data.fullurl, 'text');
  };

  // 设置消息内容 (用户消息)
  function setMessageContent(item, type = 'text') {
    state.message_list.unshift({
      bot_id: null,
      chat_id: null,
      conversation_id: null,
      createtime: item.createtime,
      follow_up: null,
      id: item.id,
      is_read: item.is_read,
      message: item.message,
      receiver_id: item.receiver_id,
      sender_id: item.sender_id,
      type,
      update_time: item.update_time,
      is_decimalPoint: false,
      voice_content: !!item.voice_content ? item.voice_content : '',
    });
  }

  // 设置消息内容 (AI消息)
  function setAIMessage(type = 'text') {
    state.message_list.unshift({
      bot_id: null,
      chat_id: null,
      conversation_id: null,
      createtime: new Date().getTime() / 1000,
      follow_up: [],
      id: state.message_list[0].id + 1,
      is_read: 0,
      message: '',
      receiver_id: state.user_info.id,
      sender_id: state.friend_info.id,
      type,
      update_time: new Date().getTime() / 1000,
      is_decimalPoint: true,
    });
  }

  // 获取键盘的高度
  const bottomHeight = (height, duration = 0) => {
    state.bottomHeight = height;
  };

  function unshare() {
    share.flag = false;
  }

  async function shareNow() {
    let arr = [];
    state.message_list.forEach(item => {
      if (item.is_select) {
        arr.push(item.id);
      }
    });
    const { data } = await sheep.$api.share.saveShareList({
      friend_id: state.friend_info.id,
      chat_ids: arr,
      id: state.ncShareInfo.id,
    });
    state.ncShareInfo.id = data.id;
    state.ncShareInfo.path = `/pages/nc_chat/index?id=${data.id}`;
  }

  // 获取任务栏的高度
  function taskbarHeight() {
    sendState.showTaskbar = !sendState.showTaskbar;
    sendHeight();
  }

  // 获取AI消息
  function getAINews(content, type = 'text') {
    // #ifdef MP-WEIXIN
    // if (!!requestTask) {
    //   requestTask.abort();
    //   requestTask = null;
    //
    // }
    setAIMessage('text');
    setScrollTop();
    requestTask = uni.request({
      url: 'https://nc.qmcyts.com/api/sse/sse',
      timeout: 100000,
      responseType: 'stream',
      method: 'POST',
      enableChunked: true,  //配置这里
      header: {
        'Accept': 'text/event-stream',
        'token': uni.getStorageSync('token'),
      },
      data: {
        uid: state.user_info.id,
        friend_id: state.friend_info.id,
        content,
        type,
        index: Number(state.message_list[0].id),
      },
      fail: error => {
        console.log('sse=>请求失败', error);
      },
    });
    requestTask.onChunkReceived(res => {
      const uint8Array = new Uint8Array(res.data);
      let text = String.fromCharCode.apply(null, uint8Array);
      text = decodeURIComponent(escape(text));
      let arr = text.split('\n');
      arr.forEach((item, index) => {
        if (item.indexOf('data') != -1) {
          if (item.split('data: ')[1] == 'DONE') {
            getAIMessage({}, false);
          } else {
            console.log('生成的消息', item);
            getAIMessage(JSON.parse(item.split('data: ')[1]));
          }
        }
      });
    });
    // #endif
    // #ifdef H5

    // #endif
  }

  // 设置AI消息
  function getAIMessage(item, flag = true) {
    nextTick(() => {
      setTimeout(() => {
        if (!!flag) {
          if (item.type == 'answer') {
            for (let i = 0; i < state.message_list.length; i++) {
              if (state.message_list[i].id == item.index) {
                state.message_list[i].message = !!state.message_list[i] && !!state.message_list[i].message ? state.message_list[i].message + item.content : item.content;
              }
            }
          }
          if (item.type == 'follow_up') {
            for (let i = 0; i < state.message_list.length; i++) {
              if (state.message_list[i].id == item.index) {
                state.message_list[i].follow_up.push(item.content);
              }
            }
          }
          setScrollTop();
        } else {
          for (let i = 0; i < state.message_list.length; i++) {
            state.message_list[i].is_decimalPoint = false;
            sheep.$store('AI').setAllSessionList();
            sheep.$store('AI').setAllFollowList();
          }
          proxy.$forceUpdate();
        }
      }, 1000);
    });
  }

  // 设置消息内容向下
  function setScrollTop() {
    nextTick(() => {
      setTimeout(() => {
        if (state.messageListHeight == 0) {
          state.messageListHeight = -1;
        } else {
          state.messageListHeight = 0;
        }
      }, 200);
    });
  }

  // 关注AI
  async function AIFollow() {
    if (state.friend_info.is_follow != 1) {
      const { data } = await sheep.$api.chat.nc_chat_follow({
        friend_id: state.friend_info.id,
      });
      state.friend_info.is_follow = 1;
      await sheep.$store('AI').setAllFollowList();
      await sheep.$store('AI').setAllSessionList();
    } else {
      const { data } = await sheep.$api.chat.nc_chat_cancel_follow({
        friend_id: state.friend_info.id,
      });
      state.friend_info.is_follow = 0;
      await sheep.$store('AI').setAllFollowList();
      await sheep.$store('AI').setAllSessionList();
    }
  }

  function onTouchStart() {
    sendState.showTaskbar = false;
    sendHeight();
  }

  function toggleMode() {
    sendState.textInput = !sendState.textInput;
  }

  function toggle() {

  }

  // 立即开通
  async function openImmediately() {
    let obj = {};
    let arr = [];
    arr.push({
      goods_id: vipDisposition.goodDetails.id,
      goods_num: 1,
      goods_sku_price_id: vipDisposition.goodDetails.id,
    });
    obj.goods_list = arr;
    obj.is_from = 1;
    obj.order_type = 'goods';
    const { code, data } = await sheep.$api.order.create(obj);
    sheep.$router.redirect('/pages/pay/index', {
      orderSN: data.order_sn,
      flag: 1,
    });
  }

  // 立即兑换
  function exchangeImmediately() {
    sheep.$router.go('/pages/vip/memberCenter');
  }

  // 关闭会员弹窗
  function closePopup() {
    vipDisposition.isShow = false;
  }

  // 播放语音
  const innerAudio = uni.createInnerAudioContext();
  let audioIndex = -1;

  function playVoice(item, index) {
    if (item.message == '') return;
    if (item.message == innerAudio.src) {
      innerAudio.stop();
      innerAudio.src = '-1';
      return;
    }
    if (audioIndex != -1) {
      state.message_list[audioIndex].isPlay = false;
    }
    audioIndex = index;
    state.message_list[index].isPlay = true;
    innerAudio.src = item.message;
    innerAudio.play();
    innerAudio.onStop((res) => {
      state.message_list[index].isPlay = false;
      innerAudio.src = '-1';
      audioIndex = -1;
    });
    innerAudio.onEnded((res) => {
      state.message_list[index].isPlay = false;
      innerAudio.src = '-1';
      audioIndex = -1;
    });
  }

  function clickToSelect(index) {
    state.message_list[index].is_select = !state.message_list[index].is_select;
    shareNow();
  }
</script>


<style scoped lang="scss">
  .follow_button {
    padding: 0 12rpx;
    height: 40rpx;
    background: #FFEBA3;
    border-radius: 20rpx;
    position: absolute;
    top: 10rpx;
    right: 39rpx;
    z-index: 999;

    .text {
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 500;
      font-size: 22rpx;
      color: #232429;
    }
  }

  .follow_share {
    padding: 0 12rpx;
    height: 40rpx;
    background: #FFEBA3;
    border-radius: 20rpx;
    position: absolute;
    top: 60rpx;
    right: 39rpx;
    z-index: 999;

    .text {
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 500;
      font-size: 22rpx;
      color: #232429;
    }
  }

  .scrollViewChat {
    position: absolute;
    transform: rotate(180deg);
  }

  .memberPopup {
    width: 750rpx;
    height: 789rpx;

    .exchange {
      width: 325rpx;
      position: absolute;
      right: 215rpx;
      top: 154rpx;
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 500;
      font-size: 28rpx;
      color: #E94F09;
      padding: 0 0 5rpx 0;
    }
  }

  .button_vip {
    position: absolute;
    left: 50%;
    bottom: 110rpx;
    transform: translate(-50%, 0);
    width: 269rpx;
    height: 82rpx;
    background: url($uni-bg-url + '/nc_vip_button.png') no-repeat;
    background-size: 269rpx 82rpx;
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: 500;
    font-size: 41rpx;
    color: #FF4206;
  }

  .chatDetail {
    position: absolute;
    left: 50%;
    bottom: 270rpx;
    transform: translate(-50%, 0);
  }
</style>
